package com.jinbei.common.util;

import com.jinbei.common.contants.Contants;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * @author zflu
 * Aes 加密工具类
 * Aes 现在用在 对@ResponseBody 和 @RerquestBody 的json 加密/解密
 * Created by lucky on 2018/8/23.
 */
public class AesUtil {

    /**
     * 算法名称
     */
    private final static String AES = "AES";

    /**
     * 加密类型
     */
    private final static String ENCRYPT_TYPE = "AES/CBC/PKCS5Padding";

    /**
     * 默认key 16位 128bit 一个字符 8个bit
     */
    private final static String DEFAULT_KEY = "!zzluckymao13.S9";

    /**
     * 加密增强 16位
     */
    private final static String VECTOR = "lanlan!$.Q123tut";

    /**
     * @author zflu
     * @Description   aes base64加密返回
     * @date 2018/8/17 16:35
     * @param data
     * @return java.lang.String
     */
    public static String encrypt(String data){
        return encrypt(data, DEFAULT_KEY , null);
    }

    /**
     * @author zflu
     * @Description  aes加密 base64加密返回
     * @date 2018/8/17 16:33
     * @param data, key
     * @return java.lang.String
     */
    public static String encrypt(String data , String key , String vector){
        String result = null;
        if(data == null){
            return result;
        }
        try {
            if(vector == null){
                vector = VECTOR;
            }
            byte[] bt = encryptByte(data.getBytes(Contants.CHARSET_NAME), key.getBytes(Contants.CHARSET_NAME) , vector.getBytes(Contants.CHARSET_NAME));
            result = Base64.getEncoder().encodeToString(bt);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * @author zflu
     * @Description   正式加密的方法
     * @date 2018/8/17 17:47
     * @param data, key
     * @return byte[]
     */
    public static byte[] encryptByte(byte[] data , byte[] key , byte[] vector) throws Exception {

        //获取加密key
        SecretKeySpec sks = new SecretKeySpec(key,AES);

        //加密增强
        IvParameterSpec iv = new IvParameterSpec(vector);

        //cipher实际完成加密操作
        Cipher cipher = Cipher.getInstance(ENCRYPT_TYPE);

        cipher.init(Cipher.ENCRYPT_MODE,sks,iv);

        return cipher.doFinal(data);
    }

    /**
     * @author zflu
     * @Description   des解密 使用默认key
     * @date 2018/8/17 17:47
     * @param data
     * @return java.lang.String
     */
    public static String decrypt(String data){
        return decrypt(data,DEFAULT_KEY,null);
    }

    /**
     * @author zflu
     * @Description   des解密 使用key
     * @date 2018/8/17 17:47
     * @param data
     * @return java.lang.String
     */
    public static String decrypt(String data , String key , String vector){
        String result = null;
        if(data == null){
            return result;
        }
        try {
            if(vector == null){
                vector = VECTOR;
            }
            byte[] dataByte = Base64.getDecoder().decode(data);
            byte[] bytes = decryptByte(dataByte,key.getBytes(Contants.CHARSET_NAME),vector.getBytes(Contants.CHARSET_NAME));
            result = new String(bytes,Contants.CHARSET_NAME);
        }catch (Exception e){
            e.printStackTrace();
        }
        return result;
    }

    /**
     * @author zflu
     * @Description   正式的解密方法
     * @date 2018/8/17 17:47
     * @param data
     * @return java.lang.String
     */
    public static byte[] decryptByte(byte[] data , byte[] key , byte[] vector) throws Exception{

        //获取加密key
        SecretKeySpec sks = new SecretKeySpec(key,AES);

        //加密增强
        IvParameterSpec iv = new IvParameterSpec(vector);

        //cipher实际完成加密操作
        Cipher cipher = Cipher.getInstance(ENCRYPT_TYPE);

        cipher.init(Cipher.DECRYPT_MODE,sks,iv);

        return cipher.doFinal(data);
    }

}
